<script>
import { Table, TableColumn } from "element-ui";
import Navigation from "./components/navigation";
import _props from "./props";
import { isEmpty } from "lodash";
// import { export_json_to_excel } from "@/utils/Export2Excel";

export default {
  components: { Table, TableColumn },
  props: {
    ...Table.props,
    ..._props,
  },
  data() {
    return {
      // multipleSelection: [], // 勾选表格
      localDataSource: [], // 数据源
      localLoading: false, // 表格loading
      localPagination: {
        // 表格分页配置
        background: true,
        layout: this.layout || "total, sizes, prev, pager, next, jumper",
        total: 0,
        pageSizes: this.pageSizes,
        pageSize: this.pageSize,
        currentPage: this.currentPage,
      },
    };
  },
  created() {
    this.autoLoad && this.loadData();
  },
  watch: {
    "localPagination.pageSize": function () {
      this.loadData();
      this.$emit("getPageSize", this.localPagination.pageSize);
    },
    "localPagination.currentPage": function () {
      this.loadData();
      this.$emit("getPage", this.localPagination.currentPage);
    },
    data: {
      handler: "loadLocalData",
      deep: true,
      immediate: true,
    },
  },
  computed: {
    getTableProps() {
      // table props 遍历
      let tableProps = {};
      Object.keys(Table.props).forEach((k) => {
        // console.log(`this[${k}]`,  this[k])
        // console.log("this是啥：", this);
        this[k] !== undefined && this[k] !== null && (tableProps[k] = this[k]);
      });
      // console.log('tableProps', Table.props.border.type())
      // 合并默认配置，统一样式，页面也可单独定制
      return {
        size: "small",
        headerCellStyle: {
          backgroundColor: "#f3f3f3",
        },
        ...tableProps,
        border: true,
        tooltipEffect: "dark",
        data: this.localDataSource,
      };
    },
  },
  methods: {
    loadLocalData() {
      if (this.showPagination) {
        // 加载本地数据方法
        const start =
          (this.localPagination.currentPage - 1) *
          this.localPagination.pageSize;
        const end =
          this.localPagination.currentPage * this.localPagination.pageSize;
        this.localDataSource = this.data.slice(start, end);
        this.localPagination.total = this.data.length;
      } else {
        this.localDataSource = this.data;
      }
    },
    // pageSize 改变时会触发
    onSizeChange(size) {
      this.localPagination.pageSize = size;
    },
    renderCell({ item, scope, text, filters, divClassName, i }) {
      const val = i?.[item.prop] ?? text;
      const [WrapComp, className] = new Map([
        [true, ["span"]],
        [!Object.is(i, undefined), ["div", divClassName]],
        [
          Object.is(item.showTooltip, true),
          ["s-tooltip", "show-tooltip-style"],
        ],
      ]).get(true);
      if (item.slotFn) {
        return (
          <WrapComp class={className}>
            {item.slotFn(
              { item: i, row: scope.row },
              { filters, column: item }
            )}
          </WrapComp>
        );
      } else if (item.dictType) {
        // 字典
        const propText = filters.dictFilter(val, item.dictType);
        return <WrapComp class={className}>{propText} </WrapComp>;
      } else {
        return <WrapComp class={className}>{val} </WrapComp>;
      }
    },
    // currentPage 改变时会触发
    onCurrentChange(current) {
      this.localPagination.currentPage = current;
    },
    exportDataToExcel() {
      const theaders = this.columns.filter((n) => n.prop && !n.hideColumn);
    },
    /**
     * 重置表单选择
     * **/
    resetTable() {
      this.selectRows = [];
      this.$emit("reset");
    },
    /**
     * 手动刷新数据
     */
    refresh(init = false) {
      if (init) {
        // 重置当前页面
        this.localPagination.currentPage = 1;
      }
      this.$refs.table.clearSelection();
      this.loadData();
    },
    getTableColumnProps(item) {
      // 原生table自带props
      return Object.keys(item).reduce((prev, key) => {
        if (TableColumn.props[key]) {
          prev[key] = item[key];
        }
        return prev;
      }, {});
    },
    resetField(field) {
      // 重置指定的搜索表单字段
      Array.isArray(field)
        ? field.forEach((n) => (this.$refs.navRef.modelValue[n] = undefined))
        : (this.$refs.navRef.modelValue[field] = undefined);
    },
    resetFields() {
      // 重置搜索表单字段
      this.$refs.navRef?.resetFields?.();
    },
    //选中状态
    toggleRowSelection(row, selected) {
      this.$refs.table.toggleRowSelection(row, selected);
    },
    clearSelection() {
      // 清空用户多选
      this.$refs.table.clearSelection();
    },
    // 获取查询表单参数 条件选择是否触发loadData事件
    handleQuery(_params = {}) {
      // 查询表单
      // const params = this.transformSearchParams?.(_params) || _params;
      this.clearSelection();
      this.localPagination.currentPage = 1;
      // console.log("查询搜索表单参数", _params);
      this.$emit("query", _params);
      this.loadData(_params);
    },
    getParams() {
      this.$emit("getParams", this.$refs?.navRef?.modelValue || {});
    },
    // 获取搜索表单的值
    getQueryParams() {
      return this.$refs?.navRef?.cacheQueryParams || {};
    },
    /**
     * 加载数据方法
     * @param {Object} pagination 分页选项器
     */
    async loadData(_params = this.getQueryParams() || {}) {
      if (Object.is(this.dataRequest, undefined)) return this.loadLocalData();
      this.localLoading = true;
      const params = this.showPagination
        ? {
            page: this.localPagination.currentPage,
            pageSize: this.localPagination.pageSize,
            ...(this.transformSearchParams?.(_params) || _params),
          }
        : _params;
      try {
        const result = await this.dataRequest(params);
        // props中的dataRequest必须返回一个Promise，且返回的数据结构需要满足 { list, pagination: { total } }
        this.localDataSource = result.list;
        // console.log("localDataSource", this.localDataSource);
        if (this.showPagination) {
          if (
            result.list.length === 0 &&
            result.total > 0 &&
            this.localPagination.currentPage > 1
          ) {
            this.localPagination.currentPage--;
          }
          this.localPagination.total = result.total;
        }

        this.localLoading = false;
      } catch (e) {
        console.error("表格数据加载失败", e);
        // 抛出异常时也需要关闭loading
        this.localLoading = false;
      } finally {
        this.$nextTick(() => {
          this.$refs.table?.doLayout();
        });
      }
    },
    indexMethod(index) {
      const num =
        (this.localPagination.currentPage - 1) * this.localPagination.pageSize;
      return index + num + 1;
    },
    // 调用表单-查询按钮动作
    searchData() {
      this.$refs.navRef.onSubmit();
    },
  },
  render() {
    const { columns, $style, $scopedSlots } = this;
    const filters = this.$options.filters;
    const getSlot = (slotName) =>
      $scopedSlots[slotName]?.({
        queryParams: this.getQueryParams(),
      });
    return (
      <div>
        {!this.hideNavigation ? (
          <Navigation
            ref="navRef"
            style={{ marginBottom: "16px" }}
            {...{
              props: {
                columns,
                navProps: this.navProps,
                style: { marginBottom: "16px" },
              },
              on: {
                add: () => this.$emit("add"),
                query: this.handleQuery,
                exportDataToExcel: this.exportDataToExcel,
                reset: this.resetTable,
              },
            }}
            scopedSlots={{
              "nav-title": () => getSlot("nav-title"),
              "nav-button": () => getSlot("nav-button"),
              suffix: () => getSlot("suffix"),
            }}
          ></Navigation>
        ) : null}
        {getSlot("header")}
        <div style="display: flex">
          {getSlot("left-content")}
          <div class="table-wrapper">
            <Table
              {...{
                key: this.tableKey,
                class: "dynamic-table",
                props: { ...this.getTableProps },
                on: this.$listeners,
                ref: "table",
                directives: [{ name: "loading", value: this.localLoading }],

              }}
            >
              {this.showSelection ? (
                <TableColumn type="selection" reserve-selection width="55" />
              ) : null}
              {this.showIndex ? (
                <TableColumn
                  fixed="left"
                  type="index"
                  index={this.indexMethod}
                />
              ) : null}
              {columns
                .filter((item) => !item.hideColumn)
                .map((item, index) => (
                  <TableColumn
                    {...{ props: this.getTableColumnProps(item) }}
                    key={item.prop ? item.prop : index}
                    scopedSlots={{
                      header:
                        item.headerSlotFn &&
                        ((scope) => item.headerSlotFn(scope)),
                      default: (scope) => {
                        const text = item.prop
                          ?.split(".")
                          ?.reduce((p, k) => p?.[k], scope.row);
                        const columnProps = item?.columnProps;
                        if (columnProps?.isMultipleRow) {
                          const row = columnProps?.rowSource
                            ?.split(".")
                            ?.reduce((p, k) => p?.[k], scope.row);
                          return row.map((i, index) => {
                            const divClassName =
                              index === row.length - 1
                                ? "tableColumnDivStyle"
                                : "tableColumnDivStyle hasBottomBorder";

                            return this.renderCell({
                              item,
                              scope,
                              text,
                              filters,
                              divClassName,
                              i,
                            });
                          });
                        } else {
                          return this.renderCell({
                            item,
                            scope,
                            text,
                            filters,
                          });
                        }
                      },
                    }}
                  ></TableColumn>
                ))}
              {getSlot("default")}
            </Table>
            {this.showPagination ? (
              <div class={$style["table-pagination"]}>
                <el-pagination
                  {...{
                    props: { ...this.localPagination },
                    on: {
                      "size-change": this.onSizeChange,
                      "current-change": this.onCurrentChange,
                    },
                  }}
                ></el-pagination>
              </div>
            ) : null}
          </div>
        </div>
      </div>
    );
  },
};
</script>

<style module>
.table-pagination {
  display: flex;
  width: 100%;
  display: -webkit-flex;
  justify-content: flex-end;
  width: 100%;
}
</style>
<style lang="scss" scoped>
.table-wrapper {
  display: flex;
  width: 100%;
  flex-direction: column;
  height: fit-content;
}
.dynamic-table {
}
.tableColumnDivStyle {
  width: 100%;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 50px;
  overflow: hidden;
  padding: 0 10px;
}
.show-tooltip-style {
  width: 100%;
  height: 50px;
  line-height: 50px;
  overflow: hidden;
  border-bottom: 1px solid #ebeef5;
  &:last-of-type {
    border-bottom: none;
  }
}
.hasBottomBorder {
  border-bottom: 1px solid #ebeef5;
}
</style>
